package ddz.logic.game;

import ch.qos.logback.classic.Logger;
import com.kaka.notice.annotation.Handler;
import ddz.constants.Crypto;
import ddz.constants.ErrCode;
import ddz.constants.ErrLevel;
import ddz.constants.OpCode;
import ddz.core.*;
import ddz.db.dao.TableDao;
import ddz.db.service.TableTokenService;
import ddz.net.LogicDataHandler;
import ddz.net.ProtocolMessage;
import ddz.protos.GameJiabei;
import ddz.protos.GameTuoguan;
import ddz.scheduler.QuartzFacade;
import org.slf4j.LoggerFactory;

/**
 * 托管
 *
 * @author zkpursuit
 */
@Handler(cmd = OpCode.cmd_trusteeship, type = String.class)
public class TuoGuanHandler extends LogicDataHandler {

    private static final Logger logger = (Logger) LoggerFactory.getLogger(TuoGuanHandler.class);

    @Override
    public void execute(ProtocolMessage msg) throws Exception {
        GameTuoguan.CsTrustee csTrustee = (GameTuoguan.CsTrustee) msg.getBody();
        TableTokenService optTokenService = this.retrieveProxy(TableTokenService.class);
        TableToken tokenInfo = optTokenService.parseToken(csTrustee.getToken());
        long deskId = tokenInfo.getDeskId();
        TableDao tableDao = this.retrieveProxy(TableDao.class);
        Player player;
        Table table = tableDao.getDesk(deskId);
        if (table == null) {
            logger.error("玩家（" + msg.uid() + "）未加入任何房间");
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.no_join_room);
            return;
        }
        player = table.getPlayerByUid(msg.uid());
        if (player == null) {
            logger.error("玩家（" + msg.uid() + "）在" + table.getId() + "房间中无对应的数据");
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.data_err);
            return;
        }
        switch (csTrustee.getType()) {
            case 0:
                player.setTimeoutCount(TrusteeType.system_auto.getTimeoutCount());
                break;
            case 1:
                player.setTimeoutCount(TrusteeType.custom.getTimeoutCount());
                break;
            case 2:
                player.setTimeoutCount(TrusteeType.none.getTimeoutCount());
                break;
            default:
                break;
        }
        tableDao.insertOrUpdateDesk(table);
        int trusteeType = getTrusteeType(player.getTimeoutCount()).getId();
        GameTuoguan.ScTrustee.Builder builder = GameTuoguan.ScTrustee.newBuilder()
                .setSeat(player.getSeatIndex())
                .setType(trusteeType);
        Player[] members = table.getPlayers();
        for (Player member : members) {
            if (member != null) {
                this.sendData(member.getUid(), Crypto.isCrypto, opcode(), builder.build().toByteArray());
            }
        }
        if (logger.isInfoEnabled()) {
            logger.info("玩家 [{}] 托管操作： [{}]", msg.uid(), csTrustee.getType());
        }
        if (csTrustee.getType() == 1) {
            //自己是操作方即刻操作
            int nextOperateSeatIdx = table.getWaitOperateSeatIndex();
            if (table.getState() != TableState.jia_bei) {
                if (nextOperateSeatIdx == player.getSeatIndex()) {
                    QuartzFacade quartzFacade = (QuartzFacade) getFacade();
                    quartzFacade.immediateSchedule(OpCode.timer_auto_play, "desk:" + table.getId());
                }
            } else if (!table.isAlreadyJiabei(player.getSeatIndex())) {
                int cmd = Integer.parseInt(OpCode.cmd_jiabei);
                int opt = OptType.buJiabei.getId();
                TableTokenService tableTokenService = this.retrieveProxy(TableTokenService.class);
                String token = tableTokenService.createToken(table.getId(), table.getStep(), player.getSeatIndex());
                byte[] jiabeiBytes = GameJiabei.CsJiabei.newBuilder()
                        .setOpt(opt)
                        .setToken(token)
                        .build().toByteArray();
                sendMessage(new ProtocolMessage(cmd, jiabeiBytes, player.getUid()));
            }
        }
    }

    private TrusteeType getTrusteeType(int timeoutCount) {
        if (timeoutCount == TrusteeType.custom.getTimeoutCount()) {
            return TrusteeType.custom;
        }
        if (timeoutCount == TrusteeType.robot.getTimeoutCount()) {
            return TrusteeType.robot;
        }
        if (timeoutCount >= TrusteeType.system_auto.getTimeoutCount()) {
            return TrusteeType.system_auto;
        }
        return TrusteeType.none;
    }

}